﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace UnvApi
{
    public class UnvPmsManager
    {
        //宇视pms系统地址、账号信息
        private static readonly string SERVER_URL = "http://172.20.96.223";
        private static readonly string USERNAME = "admin";
        private static readonly string PASSWORD = "********";

        /// <summary>
        /// 基础请求方法
        /// </summary>
        /// <param name="path">请求路径</param>
        /// <param name="method">使用的HTTP方法</param>
        /// <param name="requestBody">请求体</param>
        /// <returns>宇视pms平台原始response</returns>
        public static async Task<string> sendRequestAsync(string path, string method, string requestBody)
        {
            string response = await UnvHttpMethods.sendMessageAsync(SERVER_URL + path, USERNAME, PASSWORD, method, requestBody);
            return response;
        }
        /// <summary>
        /// 车辆通行方向
        /// </summary>
        public enum Direction
        {
            In,
            Out
        }
        /// <summary>
        /// 获取当前场内所有车辆信息
        /// </summary>
        /// <returns></returns>
        public static async Task<string> getCurrentVehicles()
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/Vehicles/InParkingLot";
            string requestBody = "{\"Num\":1,\"Limit\": 1000,\"Offset\": 0,\"QueryInfos\":[{\"QryType\": 45,\"QryCondition\": 6,\"QryData\": \"湛江气体制氧厂区\"}]}";
            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 查询通行记录（传入起止秒级时间戳）
        /// </summary>
        /// <param name="timestampStart">起始时间</param>
        /// <param name="timestampEnd">终止时间</param>
        /// <returns></returns>
        public static async Task<string> queryPassRecords(long timestampStart, long timestampEnd)
        {
            string response = await queryPassRecords(timestampStart, timestampEnd, 200, 0);
            return response;
        }
        /// <summary>
        /// 查询通行记录（传入起止秒级时间戳；单次查询限制条数；记录序号偏移量）
        /// </summary>
        /// <param name="timestampStart">起始时间</param>
        /// <param name="timestampEnd">终止时间</param>
        /// <param name="limit">单次查询限制条数</param>
        /// <param name="offset">记录序号偏移量</param>
        /// <returns></returns>
        public static async Task<string> queryPassRecords(long timestampStart, long timestampEnd, int limit, int offset)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/Vehicles/PassRecords";

            string requestBody = "{\"Num\":3,\"QueryInfos\":[" +
                "{\"QryType\":4,\"QryCondition\":3,\"QryData\":" + timestampStart + "}," +
                "{\"QryType\":4,\"QryCondition\":4,\"QryData\":" + timestampEnd + "}," +
                "{\"QryType\":4,\"QryCondition\":9}" +
                "],\"Limit\":" + limit + ",\"Offset\":" + offset + "}";

            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 查询通行记录（传入通行方向：0-进场，1-出场；起止秒级时间戳）
        /// </summary>
        /// <param name="direction">通行方向：0-进场，1-出场</param>
        /// <param name="timestampStart">起始时间</param>
        /// <param name="timestampEnd">终止时间</param>
        /// <returns></returns>
        public static async Task<string> queryPassRecords(Direction direction, long timestampStart, long timestampEnd)
        {
            string response = await queryPassRecords(direction, timestampStart, timestampEnd, 200, 0);
            return response;
        }
        /// <summary>
        /// 查询通行记录（传入通行方向：0-进场，1-出场；起止秒级时间戳；单次查询限制条数；记录序号偏移量）
        /// </summary>
        /// <param name="direction">通行方向：0-进场，1-出场</param>
        /// <param name="timestampStart">起始时间</param>
        /// <param name="timestampEnd">终止时间</param>
        /// <param name="limit">单次查询限制条数</param>
        /// <param name="offset">记录序号偏移量</param>
        /// <returns></returns>
        public static async Task<string> queryPassRecords(Direction direction, long timestampStart, long timestampEnd, int limit, int offset)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/Vehicles/PassRecords";

            string requestBody;
            if (direction == Direction.In)
            {
                //查询条件数量为4，增加过车方向为“0-进场”的查询条件
                requestBody = "{\"Num\":4,\"QueryInfos\":[{\"QryType\": 50, \"QryCondition\": 0, \"QryData\": 0},";
            }
            else if (direction == Direction.Out)
            {
                //查询条件数量为4，增加过车方向为“1-出场”的查询条件
                requestBody = "{\"Num\":4,\"QueryInfos\":[{\"QryType\": 50, \"QryCondition\": 0, \"QryData\": 1},";
            }
            else
            {
                //输入的direction不合法，忽视此条件
                requestBody = "{\"Num\":3,\"QueryInfos\":[";
            }
            //查询条件：起止时间，按时间倒叙排序
            requestBody += "{\"QryType\":4,\"QryCondition\":3,\"QryData\":" + timestampStart + "}," +
                "{\"QryType\":4,\"QryCondition\":4,\"QryData\":" + timestampEnd + "}," +
                "{\"QryType\":4,\"QryCondition\":9}],\"Limit\":" + limit + ",\"Offset\":" + offset + "}";

            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 获取车辆分组信息
        /// </summary>
        /// <returns></returns>
        public static async Task<string> getVehicleGroups()
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle/Groups";
            string requestBody = "{}";

            string response = await sendRequestAsync(requestPath, "GET", requestBody);
            return response;
        }
        /// <summary>
        /// 根据车辆分组查询授权车辆信息（每次最多200条）
        /// </summary>
        /// <param name="groupId">车辆分组id</param>
        /// <returns></returns>
        public static async Task<string> queryAllowedVehicles(int groupId)
        {
            string response = await queryAllowedVehicles(groupId, 200, 0);
            return response;
        }
        /// <summary>
        /// 根据车辆分组查询授权车辆信息（传入查询条数限制、序号偏移量）
        /// </summary>
        /// <param name="groupId">车辆分组id</param>
        /// <param name="limit">查询条数限制</param>
        /// <param name="offset">序号偏移量</param>
        /// <returns></returns>
        public static async Task<string> queryAllowedVehicles(int groupId, int limit, int offset)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle/List";
            string requestBody = "{\"Limit\":"+limit+",\"Offset\":"+offset+",\"QueryInfos\":[{\"QryType\":100,\"QryCondition\":0,\"QryData\":"+groupId+"}],\"Num\":1}";

            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 通过部门、车牌号、车主姓名查询授权车辆信息（若不限制查询条件，则在对应的参数位置传入空字符串""）
        /// </summary>
        /// <param name="departmentId">部门id，通过getVehicleGroups()获取</param>
        /// <param name="plateNo">车牌号码</param>
        /// <param name="ownerName">车主姓名</param>
        /// <returns></returns>
        public static async Task<string> queryAllowedVehicles(string departmentId, string plateNo, string ownerName)
        {
            string response = await queryAllowedVehicles(departmentId, plateNo, ownerName, 200, 0);
            return response;
        }
        /// <summary>
        /// 通过部门、车牌号、车主姓名查询授权车辆信息（若不限制查询条件，则在对应的参数位置传入空字符串""）
        /// </summary>
        /// <param name="departmentId">部门id，通过getVehicleGroups()获取</param>
        /// <param name="plateNo">车牌号码</param>
        /// <param name="ownerName">车主姓名</param>
        /// <param name="limit">单次查询条数限制（最大为200）</param>
        /// <param name="offset">查询序号偏移量</param>
        /// <returns></returns>
        public static async Task<string> queryAllowedVehicles(string departmentId, string plateNo, string ownerName, int limit, int offset)
        {
            //查询人员信息url:/LAPI/V1.0/PeopleLibraries/0/People/Info
            //根据部门（101-宝粤气体）：{"QryType": 100, "QryCondition": 0, "QryData": 101}
            //根据车牌号：{"QryType":129,"QryCondition":6,"QryData":"粤GF20038"}
            //根据车主姓名：{"QryType": 119, "QryCondition": 0, "QryData": "周俊延"}

            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle/List";
            string requestBody = "{\"Limit\": "+limit+", \"Offset\": "+offset+", \"Num\": 0}";

            //判断传入的查询条件是否为空,非空则构建新的requestBody
            int conditions = 0;
            string conditionString = "";
            if (departmentId != "")
            {
                conditions++;
                conditionString += "{\"QryType\": 100, \"QryCondition\": 0, \"QryData\": " + departmentId + "},";
            }
            if (plateNo != "")
            {
                conditions++;
                conditionString += "{\"QryType\":129,\"QryCondition\":6,\"QryData\":\"" + plateNo + "\"},";
            }
            if (ownerName != "")
            {
                conditions++;
                conditionString += "{\"QryType\": 119, \"QryCondition\": 0, \"QryData\": \"" + ownerName + "\"},";
            }
            if (conditions > 0)
            {
                conditionString = conditionString.Substring(0, conditionString.Length - 1);
                requestBody = "{\"Limit\": 200, \"Offset\": 0, \"QueryInfos\": [" + conditionString + "], \"Num\": " + conditions + "}";
            }

            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 生成添加授权车辆json字符串
        /// </summary>
        /// <param name="vehicleInfo"></param>
        /// <returns></returns>
        private static string generateVehiclePermissionJson(VehicleInfo vehicleInfo)
        {
            string json = "{\"AllowedInfo\":{\"Remarks\":\"\",\"StartTime\":"+vehicleInfo.LifeSpanStart+",\"EndTime\":"+vehicleInfo.LifeSpanEnd+",\"Status\":\"\"},";
            //车牌号
            json += "\"AllowedVehicleDetailInfo\":{\"VehicleAuthorityID\":1,\"AllowedVehicleID\":\"\",\"PlateNo\":\"" + vehicleInfo.PlateNo + "\",";
            //车辆类型VehicleType：3-小型车，4-大型车；车辆颜色、车牌颜色、车牌类型，默认即可，不重要。
            json += "\"VehicleType\":" + vehicleInfo.VehicleType + ",\"VehicleColor\":1,\"PlateColor\":4,\"PlateType\":1,";
            //车辆分组，通过getVehicleGroups()方法获取组号
            json += "\"AllowedVehicleGroupID\":" + vehicleInfo.GroupID + ",";
            //如果AllowedVehicleID不为空，也加进去
            if(vehicleInfo.AllowedVehicleID != null)
            {
                json += "\"AllowedVehicleID\":" + vehicleInfo.AllowedVehicleID + ",";
            }
            //车主人信息
            json += "\"OwnerInfo\":{\"PersonID\":\"\",\"Name\":\"" + vehicleInfo.OwnerName + "\",\"Phone\":\"" + vehicleInfo.Phone + "\",\"Address\":\"\",\"Identification\":{\"Type\":0,\"Number\":\"" + vehicleInfo.OwnerID + "\"}}},";
            //车辆图片等信息
            json += "\"VehicleImage\":{\"Name\":\"\",\"Size\":\"\",\"Data\":\"\"},\"ReqSeq\":21}";
            return json;
        }
        /// <summary>
        /// 添加授权车辆
        /// </summary>
        /// <param name="vehicleInfo"></param>
        /// <returns></returns>
        public static async Task<string> addVehicle(VehicleInfo vehicleInfo)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle";
            string requestBody = "{\"Num\":1,\"AllowedVehicleInfoList\":[";
            //授权有效期（秒级时间戳，起止时间均为0则为长期有效）
            requestBody += generateVehiclePermissionJson(vehicleInfo);
            requestBody += "]}";

            Console.WriteLine(requestBody);
            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 添加授权车辆
        /// </summary>
        /// <param name="vehicleInfos"></param>
        /// <returns></returns>
        public static async Task<string> addVehicle(List<VehicleInfo> vehicleInfos)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle";
            string requestBody = "{\"Num\":"+vehicleInfos.Count+",\"AllowedVehicleInfoList\":[";
            foreach(VehicleInfo vehicleInfo in vehicleInfos)
            {
                requestBody += generateVehiclePermissionJson(vehicleInfo) + ",";
            }
            //去掉最后一个逗号
            requestBody = requestBody.Substring(0, requestBody.Length-1);
            requestBody += "]}";

            Console.WriteLine(requestBody);
            string response = await sendRequestAsync(requestPath, "POST", requestBody);
            return response;
        }
        /// <summary>
        /// 删除授权车辆
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static async Task<string> deleteVehicle(int id)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle";

            var json = new
            {
                Num = 1,
                IDList = new int[] { id }
            };
            string requestBody = UnvHttpMethods.generateJsonString(json);

            string response = await sendRequestAsync(requestPath, "DELETE", requestBody);
            return response;
        }
        public static async Task<string> deleteVehicles(int[] idList)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle";

            var json = new
            {
                Num = idList.Length,
                IDList = idList
            };
            string requestBody = UnvHttpMethods.generateJsonString(json);

            string response = await sendRequestAsync(requestPath, "DELETE", requestBody);
            return response;
        }
        public static async Task<string> updateVehicle(VehicleInfo vehicleInfo)
        {
            string requestPath = "/LAPI/V1.0/ParkingLots/AllowedVehicle/" + vehicleInfo.AllowedVehicleID;

            string requestBody = generateVehiclePermissionJson(vehicleInfo);

            string response = await sendRequestAsync(requestPath, "PUT", requestBody);
            return response;
        }
    }
}
